using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing ;
using System.Windows.Forms ;

namespace dohoa2
{
// Add comment
    class Cline : Chinhve
    {
        // Point dau, cuoi, tamquay,tinhtien;
        public Point dau, cuoi;
        int xx, yy, xx2, yy2;
        int x, y, x2, y2;

        float m, b;
        int exp = 3;
        double[,] matranbiendoi;
            double[] matrantam;
        int gocquay=0;
        // public Bitmap anh;
        // public Color maunen,mauve=Color.Green  ;

        int kieuduongthang = 0;
        public Cline(Color maunen1)
        {
            khoitao();
            maunen = maunen1;
            capnhatgiatrichoxyx2y2();
        }
        
        public Cline() 
        {
            khoitao();
            capnhatgiatrichoxyx2y2();
        }
        public Cline(Bitmap hinh, Color mn, Point m, Point hh)
        {
            anh = hinh; maunen = mn;
            khoitao();
            dau = m; cuoi = hh;
            capnhatgiatrichoxyx2y2();
        }
        public Cline(Bitmap hinh, Color mn, int xxx, int yyy, int xxx2, int yyy2)
        {
            anh = hinh;
            maunen = mn;
            khoitao();

            dau.X = xxx; dau.Y = yyy;
            cuoi.X = xxx2; cuoi.Y = yyy2;
            capnhatgiatrichoxyx2y2();
        }
        private void khoitao()
        {
            matrantam = new double[3];
           for (int i = 0; i < 3; matrantam[i] = 0, i++) ; 
           // matrantam.SetValue(0, 0, 2);
            matranbiendoi = new double[3, 3];
            ganmatranbiendoimacdinh();

            dau = new Point();
            cuoi = new Point();
        }
        private void ganmatranbiendoimacdinh()
        {
            matranbiendoi[0, 0] = 1;
            matranbiendoi[0, 1] = 0;
            matranbiendoi[0, 2] = 0;
            matranbiendoi[1, 0] = 0;
            matranbiendoi[1, 1] = 1;
            matranbiendoi[1, 2] = 0;
            matranbiendoi[2, 0] = 0;
            matranbiendoi[2, 1] = 0;
            matranbiendoi[2, 2] = 1;
        }

        private void biendoi(out int x,out int y,out int x2,out int y2)
        {
            int i,j;
           int[] aa=new int[3];
           for ( i = 0; i < 3; i++) matrantam[i] = 0; 
           aa[ 0] = dau.X;
           aa[ 1] = dau.Y;
           aa[ 2] = 1;
           for (i = 0; i < 3; i++)
               for (j = 0; j < 3; j++)
                   matrantam[i] += matranbiendoi[i, j] * aa[j];
            x = (int)matrantam[0];
            y = (int)matrantam[1];

            for (i = 0; i < 3; i++) matrantam[i] = 0; 
            aa[0] = cuoi.X;
            aa[1] = cuoi.Y;
            aa[2] = 1;
            for (i = 0; i < 3; i++)
                for (j = 0; j < 3; j++)
                    matrantam[i] += matranbiendoi[i, j] * aa[j];
            x2 = (int)matrantam[0];
            y2 = (int)matrantam[1];
        }
        private void capnhatgiatrichoxyx2y2()
        {
            biendoi(out xx, out yy, out xx2,out  yy2);
          // if (x<0 || y<0 || x2<0) MessageBox.Show("dau.X:" + dau.X + " x:" + x.ToString()
          //      +" dau.Y:" + dau.Y + " y:" + y.ToString()
           //     );

        }
        

        public void veDDA()
        {
            //   MessageBox.Show("dang o thu tuc DDA "+"dau:" + dau.X.ToString() + " " + dau.Y.ToString() + " "
            //     + " cuoi:" + cuoi.X.ToString() + " " + cuoi.Y.ToString());
           x = xx; y = yy;
           x2 = xx2; y2 = yy2;
       //   x2 = cuoi.X; y2 = cuoi.Y;
        // capnhatgiatrichoxyx2y2();
            float m, le = (float)y;

            if (x2 == x)
            {
                if (y < y2) for (; y < y2; y++) anh.SetPixel(x, y, mauve);
                else for (; y2 < y; y2++) anh.SetPixel(x, y2, mauve);

                return;
            }

            if (y2 == y)
            {
                if (x < x2) for (; x < x2; x++) anh.SetPixel(x, y, mauve);
                else for (; x2 < x; x2++) anh.SetPixel(x2, y, mauve);

                return;
            }


            m = (float)(y2 - y) / (x2 - x);


            if ((m <= 1) && (m >= -1))
            {
                if (x < x2)
                {
                    anh.SetPixel(x, y, mauve);

                    while (x < x2)
                    {
                        x++;
                        le += m;
                        anh.SetPixel(x, round(le), mauve);
                    }
                }
                else
                {
                    m = -m;
                    anh.SetPixel(x2, y, mauve);

                    while (x > x2)
                    {
                        x--;
                        le += m;
                        anh.SetPixel(x, round(le), mauve);
                    }
                }
            }
            else // tang nhanh
            {
                m = (float)(x2 - x) / (y2 - y);
                le = (float)(x);
                if (y < y2)
                {
                    anh.SetPixel(x, y, mauve);

                    while (y < y2)
                    {
                        y++;
                        le += m;
                        anh.SetPixel(round(le), y, mauve);
                    }
                }
                else
                {
                    m = -m;
                    anh.SetPixel(x, y2, mauve);

                    while (y > y2)
                    {
                        y--;
                        le += m;
                        anh.SetPixel(round(le), y, mauve);
                    }
                }
            }



        }

        public void veMid()
        {
            //x = dau.X; y = dau.Y;
            //x2 = cuoi.X; y2 = cuoi.Y;
            x = xx; y = yy;
            x2 = xx2; y2 = yy2;
            int dx, dy, p = 0, h1 = 0, h2 = 0;

            dx = x2 - x;
            dy = y2 - y;
            float m = (float)dy / (float)dx;

            if (x2 == x)
            {
                if (y < y2) for (; y < y2; y++) anh.SetPixel(x, y, mauve);
                else for (; y2 < y; y2++) anh.SetPixel(x, y2, mauve);

                return;
            }

            if (y2 == y)
            {
                if (x < x2) for (; x < x2; x++) anh.SetPixel(x, y, mauve);
                else for (; x2 < x; x2++) anh.SetPixel(x2, y, mauve);

                return;
            }


            if ((m > 0) && (m <= 1)) // tang cham
            {
                h1 = 2 * dy;
                h2 = 2 * dy - 2 * dx;
                p = 2 * dy - dx;

                if ((x > x2) && (y > y2))
                {
                    int tam = x;
                    x = x2;
                    x2 = tam;

                    tam = y;
                    y = y2;
                    y2 = tam;
                    dx = -dx; dy = -dy;
                    h1 = 2 * dy;
                    h2 = 2 * dy - 2 * dx;
                    p = 2 * dy - dx;
                }
                //txt1.Text = "x:" + x.ToString() + " x2:" + x2.ToString()
                // + " ///y:" + y.ToString() + " y2:" + y2.ToString();
                anh.SetPixel(x, y, mauve);
                while (x < x2)
                {
                    if (p < 0)
                    {
                        p += h1;
                    }
                    else
                    {
                        p += h2;
                        y++;
                    }
                    x++;
                    anh.SetPixel(x, y, mauve);
                }
                return;
            }

            if ((m < 0) && (m > -1)) // giam cham
            {
                h2 = 2 * dy;
                h1 = 2 * dy + 2 * dx;

                anh.SetPixel(x, y, mauve);
                if ((x > x2) && (y < y2))
                {
                    int tam = x;
                    x = x2;
                    x2 = tam;

                    tam = y;
                    y = y2;
                    y2 = tam;
                    dx = -dx; dy = -dy;
                    h2 = 2 * dy;
                    h1 = 2 * dy + 2 * dx;
                    p = 2 * dy - dx;
                }
                while (x < x2)
                {
                    if (p < 0)
                    {
                        p += h1;
                        y--;
                    }
                    else
                    {
                        p += h2;

                    }
                    x++;
                    anh.SetPixel(x, y, mauve);
                }
                return;
            }

            if (m > 1) // tang nhanh
            {
                h1 = 2 * dy + 2 * (-dx);
                h2 = 2 * (-dx);

                p = dy + h2;

                anh.SetPixel(x, y, mauve);
                if ((x > x2) && (y > y2))
                {
                    int tam = x;
                    x = x2;
                    x2 = tam;

                    tam = y;
                    y = y2;
                    y2 = tam;
                    dx = -dx; dy = -dy;
                    h1 = 2 * dy + 2 * (-dx);
                    h2 = 2 * (-dx);
                    p = dy + h2;
                }

                while (y < y2)
                {
                    if (p <= 0)
                    {
                        p += h1;
                        x++;
                    }
                    else
                    {
                        p += h2;

                    }
                    y++;
                    anh.SetPixel(x, y, mauve);
                }
                return;
            }

            if (m < -1) // giam nhanh
            {
                h1 = 2 * dy + 2 * dx;
                h2 = 2 * (dx);
                p = dy + 2 * dx;

                anh.SetPixel(x, y, mauve);
                if ((x > x2) && (y < y2))
                {
                    int tam = x;
                    x = x2;
                    x2 = tam;

                    tam = y;
                    y = y2;
                    y2 = tam;

                    dx = -dx; dy = -dy;
                    h1 = 2 * dy + 2 * (dx);
                    h2 = 2 * (dx);
                    p = dy - 2 * (-dx);
                }

                while (y2 < y)
                {
                    if (p <= 0)
                    {
                        p += h2;
                    }
                    else
                    {
                        p += h1;
                        x++;

                    }
                    y--;
                    anh.SetPixel(x, y, mauve);
                }
                return;
            }

        }

        public override void ve()
        {
            if (kieuduongthang == 0) veDDA();
            else veMid();
        }
        public override void vechon()
        {
          // x = dau.X; y = dau.Y;
          // x2 = cuoi.X; y2 = cuoi.Y;
          //  capnhatgiatrichoxyx2y2();
            //x = xx; y = yy;
            //x2 = xx2; y2 = yy2;
            veonho(xx, yy);
            veonho(xx2, yy2);

        }

        public override bool kiemtraduocchon(Point p)//, TextBox t)
        {
            //x = dau.X; y = dau.Y;
            //x2 = cuoi.X; y2 = cuoi.Y;
        //   capnhatgiatrichoxyx2y2();
            x = xx; y = yy;
            x2 = xx2; y2 = yy2;
            if (dau.X < cuoi.X) if (!((dau.X <= p.X) && (p.X <= cuoi.X))) return false;
            if (dau.X >= cuoi.X) if (!((dau.X >= p.X) && (p.X >= cuoi.X))) return false;

            if (dau.Y < cuoi.Y) if (!((dau.Y <= p.Y) && (p.Y <= cuoi.Y))) return false;
            if (dau.Y >= cuoi.Y) if (!((dau.Y >= p.Y) && (p.Y >= cuoi.Y))) return false;

            if (x != x2)
            {
                m = (float)(y2 - y) / (float)(x2 - x);
                b = y - m * x;
                float yyyy = m * p.X + b;

                // t.Text += " " + abs(yy - p.Y).ToString();
                // MessageBox.Show("xin chao"); 

                if (Math.Abs(yyyy - p.Y) < exp)
                { //duocchon = true;
                    return true;
                }
                else
                { //duocchon = false;
                    return false;
                }
            }
            //duocchon = false; 
            return false;
        }


        private int round(float a)
        {
            return (int)(a + 0.5);
        }

        public override void tinhtien(Point mot, Point hai)
        {
            int dx, dy;
            Color mauluu = new Color();
            mauluu = mauve;
            mauve = maunen;
            ve();
            if (duocchon == true) bochon();

            mauve = mauluu;
            dx = hai.X - mot.X;
            dy = hai.Y - mot.Y;

            if ((dau.X + dx - kichthuoconho / 2 >= 0) && (dau.X + dx + kichthuoconho / 2) <= anh.Width
                && (cuoi.X + dx - kichthuoconho / 2) >= 0 && (cuoi.X + dx + kichthuoconho / 2) <= anh.Width
                && (dau.Y + dy - kichthuoconho / 2 >= 0) && (dau.Y + dy + kichthuoconho / 2) <= anh.Height
                && (cuoi.Y + dy - kichthuoconho / 2) >= 0 && (cuoi.Y + dy + kichthuoconho / 2) <= anh.Height
            )
            {
                dau.X += dx;
                cuoi.X += dx;
                dau.Y += dy;
                cuoi.Y += dy;
            }
            capnhatgiatrichoxyx2y2();
            ve();
            if (duocchon == true) vechon();


        }

        public override void quay(Point mot, Point hai)
        {
            Color mauluu = new Color();
            mauluu = mauve;
            mauve = maunen;
            ve();
            if (duocchon == true) bochon();

            mauve = mauluu;
            
            //x = xx; y = yy;
            //x2 = xx2; y2 = yy2;
            int tamx,tamx2,tamy2, tamy;
            tamx =tamx2= (dau.X + cuoi.X) / 2;
            tamy =tamy2= (dau.Y + cuoi.Y) / 2;
          //  
            Point tam = new Point();
            tam.X = tamx;
            tam.Y = tamy;


            double Cosgoc = (dodaimu2(mot, hai) - dodaimu2(tam, mot) - dodaimu2(tam, hai)) / (-2 * dodai(tam, mot) * dodai(tam, hai));
            double goc = Math.Acos(Cosgoc);
           //goc = goc * Math.PI / 180;
            gocquay += (int)goc;
            if (gocquay > 360) gocquay = gocquay % 360;
            //Cosgoc = Math.Cos(goc);
            Cosgoc = Math.Cos(gocquay * Math.PI / 180);
            double Singoc = Math.Sin(gocquay * Math.PI / 180);
            //double Singoc = 1 - Cosgoc * Cosgoc; //Math.Sin(goc);// 

            matranbiendoi[0, 0] = Cosgoc;
            matranbiendoi[0, 1] = -Singoc;
            matranbiendoi[1, 0] = Singoc;
            matranbiendoi[1, 1] = Cosgoc;

            xx = dau.X - tamx2;            yy = dau.Y - tamy2;
            xx2 = cuoi.X - tamx2;            yy2 = cuoi.Y - tamy2;
            //MessageBox.Show("tamx:" + tamx2.ToString() + " tamy:" + tamy2.ToString());
            capnhatgiatrichoxyx2y2();
            xx = dau.X + tamx2;            yy = dau.Y + tamy2;
            xx2 = cuoi.X + tamx2;           yy2 = cuoi.Y + tamy2;

            /*dau.X += -tamx;            cuoi.X += -tamx;
            dau.Y += -tamy;            cuoi.Y += -tamy;

            tamx = (int)(dau.X * Cosgoc - dau.Y * Singoc);
            tamy = (int)(dau.X * Singoc + dau.Y * Cosgoc);
            dau.X = tamx; dau.Y = tamy;
           
            dau.X += tamx2; dau.Y += tamy2;
           
            tamx = (int)(cuoi.X * Cosgoc - cuoi.Y * Singoc);
            tamy = (int)(cuoi.X * Singoc + cuoi.Y * Cosgoc);
            cuoi.X = tamx; cuoi.Y = tamy;
            cuoi.X += tamx2; cuoi.Y += tamy2;
             */
            ve();


            if (duocchon == true) vechon();
            //   MessageBox.Show("hihi"); 
        }

        public override void quay1goc(int goc)
        {
            Color mauluu = new Color();
            mauluu = mauve;
            mauve = maunen;
            ve();
            if (duocchon == true) bochon();

            mauve = mauluu;
            
            int tamx,tamx2,tamy2, tamy;
            tamx =tamx2= (dau.X + cuoi.X) / 2;
            tamy =tamy2= (dau.Y + cuoi.Y) / 2;
           // MessageBox.Show("tamx:" + tamx.ToString() + " tamx2:" + tamx2.ToString());

            double Cosgoc = Math.Cos(goc*Math.PI/180);
            double Singoc = Math.Sin(goc*Math.PI/180);
      
            dau.X += -tamx;            cuoi.X += -tamx;
            dau.Y += -tamy;            cuoi.Y += -tamy;

            tamx = (int)(dau.X * Cosgoc - dau.Y * Singoc);
            tamy = (int)(dau.X * Singoc + dau.Y * Cosgoc);
            dau.X = tamx; dau.Y = tamy;
            dau.X += tamx2; dau.Y += tamy2;

            tamx = (int)(cuoi.X * Cosgoc - cuoi.Y * Singoc);
            tamy = (int)(cuoi.X * Singoc + cuoi.Y * Cosgoc);
            cuoi.X = tamx; cuoi.Y = tamy;
            cuoi.X += tamx2; cuoi.Y += tamy2;

            ve();

            if (duocchon == true) vechon();
        }

        public void tinhtien2(int a,int b)
        {
            dau.X += a;
            cuoi.X += a;
            dau.Y+=b;
            cuoi.Y += b;
        }
    }
}
